function BootStatsOOS = BootOOS(XBootOOS, YBoot, OOSBeg, PredSgn, gam, MktVar, Rf)

global BootOOSstruct;

[T, NBoot] = size(YBoot); % XBoot is assumed to be only a single variable
BootStatsOOS = repmat(BootOOSstruct,NBoot,1);

for b = 1:NBoot
    XOOS = XBootOOS(:,:,b); Y = YBoot(:,b);

    YMdl = NaN(T,1); YUnc = NaN(T,1);
    WtMdl = NaN(T,1); WtUnc = NaN(T,1);
    for t = OOSBeg-1:T-1
        y = Y(2:t); x = [ones(length(y),1) XOOS(1:t-1,t)];
        bols = x\y;
        YMdl(t+1) = [1 XOOS(t,t)]*bols;
        YUnc(t+1) = mean(y);

        WtMdl(t+1) = YMdl(t+1)/(gam * MktVar);
        WtUnc(t+1) = YUnc(t+1)/(gam * MktVar);
    end

    ErrMdl = Y - YMdl; ErrUnc = Y - YUnc;
    EMdl = ErrMdl(OOSBeg:T); EUnc = ErrUnc(OOSBeg:T);
    SE1 = EUnc.^2; SE2 = EMdl.^2;
    d = SE1 - SE2; P = length(d);
    c = EUnc.*(EUnc - EMdl);
    BootStatsOOS(b).R2 = 1 - mean(SE2)/mean(SE1);
    BootStatsOOS(b).DMAE = mean(abs(EMdl)) - mean(abs(EUnc));
    BootStatsOOS(b).MSET = sqrt(P)*mean(d)/std(d);
    BootStatsOOS(b).MSEF = P*mean(d)/mean(SE2);
    BootStatsOOS(b).ENCT = sqrt(P)*mean(c)/std(c);
    BootStatsOOS(b).ENCF = P*mean(c)/mean(SE2);
    BootStatsOOS(b).ENClambd = (EUnc-EMdl)\EUnc;

    % Add Campbell/Thomson restriction - if forecast < 0, set it to zero
    YMdl(YMdl<0) = 0; YUnc(YUnc<0) = 0;
    ErrMdl = Y - YMdl; ErrUnc = Y - YUnc;
    EMdl = ErrMdl(OOSBeg:T); EUnc = ErrUnc(OOSBeg:T);
    SE1 = EUnc.^2; SE2 = EMdl.^2;
    d = SE1 - SE2; P = length(d);
    c = EUnc.*(EUnc - EMdl);
    BootStatsOOS(b).R2_CT = 1 - mean(SE2)/mean(SE1);
    BootStatsOOS(b).DMAE_CT = mean(abs(EMdl)) - mean(abs(EUnc));
    BootStatsOOS(b).MSET_CT = sqrt(P)*mean(d)/std(d);
    BootStatsOOS(b).MSEF_CT = P*mean(d)/mean(SE2);
    BootStatsOOS(b).ENCT_CT = sqrt(P)*mean(c)/std(c);
    BootStatsOOS(b).ENCF_CT = P*mean(c)/mean(SE2);
    BootStatsOOS(b).ENClambd_CT = (EUnc-EMdl)\EUnc;

    % Do utiity calculations. Weights are constrained to be between 0% and 150%
    % These calculations use NON CT forecasts
    WtMdl(WtMdl<0) = 0; WtMdl(WtMdl>1.5) = 1.5; RportMdl = WtMdl.*Y + Rf; RportMdl = RportMdl(OOSBeg:T);
    WtUnc(WtUnc<0) = 0; WtUnc(WtUnc>1.5) = 1.5; RportUnc = WtUnc.*Y + Rf; RportUnc = RportUnc(OOSBeg:T);
    UtilMdl = mean(RportMdl) - 0.5*gam*var(RportMdl);
    UtilUnc = mean(RportUnc) - 0.5*gam*var(RportUnc);
    V = cov(RportMdl,RportUnc);
    Sig = [V zeros(2); zeros(2) 2*(V.^2)];
    D = [1; -1; -gam/2; gam/2];
    BootStatsOOS(b).DiffUtil1 = UtilMdl - UtilUnc;
    BootStatsOOS(b).DiffUtil1t = (UtilMdl - UtilUnc)/sqrt(D'*Sig*D/P);

    % add always 100% in market
    RportMkt = Y + Rf; RportMkt = RportMkt(OOSBeg:T);
    UtilMkt = mean(RportMkt) - 0.5*gam*var(RportMkt);
    V = cov(RportMdl,RportMkt);
    Sig = [V zeros(2); zeros(2) 2*(V.^2)];
    D = [1; -1; -gam/2; gam/2];
    BootStatsOOS(b).DiffUtil2 = UtilMdl - UtilMkt;
    BootStatsOOS(b).DiffUtil2t = (UtilMdl - UtilMkt)/sqrt(D'*Sig*D/P);

    % Construct simple strategies
    RetStrat = NaN(T, 4);
    for t = OOSBeg-1:T-1
        Xt = XOOS(1:t,t); Xt(~isfinite(Xt)) = [];
        Xstd = std(Xt); Xmedian = median(Xt);
        % four cases: (1) InvestZ && Threshold==50; (2) InvestZ && Threshold==25; (3) ~InvestZ && Threshold==50; (4) ~InvestZ && Threshold==25
        XBrkPt = NaN(4,1);          zscore = NaN(4,1);
        if PredSgn(b) >= 0
            XBrkPt(1) = Xmedian;        zscore(1) = (Xt(end) - XBrkPt(1)) / Xstd;
            XBrkPt(2) = prctile(Xt,25); zscore(2) = (Xt(end) - XBrkPt(2)) / Xstd;
            XBrkPt(3) = Xmedian;        zscore(3) = 1;
            XBrkPt(4) = prctile(Xt,25); zscore(4) = 1;
        else
            XBrkPt(1) = Xmedian;        zscore(1) = (Xt(end) - XBrkPt(1)) / Xstd;
            XBrkPt(2) = prctile(Xt,75); zscore(2) = (Xt(end) - XBrkPt(2)) / Xstd;
            XBrkPt(3) = Xmedian;        zscore(3) = 1;
            XBrkPt(4) = prctile(Xt,75); zscore(4) = 1;
        end
        zscore = abs(zscore);
        Sgn = PredSgn(b) * sign(Xt(end) - XBrkPt); Sgn(Sgn==0) = 1;
        RetStrat(t+1,:) = (Sgn - 1) .* zscore * Y(t+1); % Double difference; Long-Short; XVar-Mkt
    end
    m = mean(RetStrat,'omitnan'); s = std(RetStrat,'omitnan'); n = sum(isfinite(RetStrat)); BootStatsOOS(b).DLSt = sqrt(n).*m./s;
    mSR = m./s; sSR = sqrt((mSR.^2 + 2)./(2*n)); BootStatsOOS(b).DLSSRt = mSR./sSR;
end
return